import React, { PureComponent } from "react";
import classNames from "classnames";
import { Menu, Icon } from "antd";
import Link from "umi/link";
import { urlToList } from "../_utils/pathTools";
import { getMenuMatches } from "./SiderMenuUtils";
import { isUrl, isPng } from "@/utils/utils";
import styles from "./index.less";
import IconFont from "@/components/IconFont";

const { SubMenu } = Menu;

// Allow menu.js config icon as string or ReactNode
//   icon: 'setting',
//   icon: 'icon-geren' #For Iconfont ,
//   icon: 'http://demo.com/icon.png',
//   icon: <Icon type="setting" />,
const getIcon = (icon, selectKey) => {
	if (typeof icon === "string") {
		if (isUrl(icon)) {
			return (
				<Icon
					component={() => (
						<img src={icon} alt='icon' className={styles.icon} />
					)}
				/>
			);
		}
		if (isPng(icon)) {
			let iconDom =
				selectKey && (selectKey + ".png").indexOf(icon) > -1 ? (
					<Icon
						component={() => (
							<img
								src={"/menuIcons/" + selectKey + "d.png"}
								alt='icon'
								className={styles.icon}
							/>
						)}
					/>
				) : (
					<Icon
						component={() => (
							<img
								src={"/menuIcons/" + icon}
								alt='icon'
								className={styles.icon}
							/>
						)}
					/>
				);

			return iconDom;
		}
		if (icon.startsWith("icon-")) {
			return <IconFont type={icon} />;
		}
		return <Icon type={icon} />;
	}
	return icon;
};

export default class BaseMenu extends PureComponent {
	/**
	 * 获得菜单子节点
	 * @memberof SiderMenu
	 */
	getNavMenuItems = (menusData, selectKey) => {
		if (!menusData) {
			return [];
		}
		return menusData
			.filter((item) => item.name && !item.hideInMenu)
			.map((item) => this.getSubMenuOrItem(item, selectKey))
			.filter((item) => item);
	};

	// Get the currently selected menu
	getSelectedMenuKeys = (pathname) => {
		const { flatMenuKeys } = this.props;
		return urlToList(pathname).map((itemPath) =>
			getMenuMatches(flatMenuKeys, itemPath).pop()
		);
	};

	/**
	 * get SubMenu or Item
	 */
	getSubMenuOrItem = (item, selectKey) => {
		// doc: add hideChildrenInMenu
		if (item.children && !item.hideChildrenInMenu && item.children.some((child) => child.name)) {
			const { name } = item;
			return (
				<SubMenu title={item.icon ? <span>{getIcon(item.icon, selectKey)}<span>{name}</span></span> : name} key={item.path}>
					{this.getNavMenuItems(item.children, selectKey)}
				</SubMenu>
			);
		};

		return (
			<Menu.Item key={item.path}>{this.getMenuItemPath(item, selectKey)}</Menu.Item>
		);
	};

	/**
	 * 判断是否是http链接.返回 Link 或 a
	 * Judge whether it is http link.return a or Link
	 * @memberof SiderMenu
	 */
	getMenuItemPath = (item, selectKey) => {
		const { name } = item;
		const itemPath = this.conversionPath(item.path);
		const icon = getIcon(item.icon, selectKey);
		const { target } = item;
		// Is it a http link
		if (/^https?:\/\//.test(itemPath)) {
			return (
				<a href={itemPath} target={target}> {icon} <span>{name}</span> </a>
			);
		};
		const { location, isMobile, onCollapse } = this.props;

		return (
			<Link to={itemPath} target={target} replace={itemPath === location.pathname} onClick={isMobile ? () => { onCollapse(true); } : undefined}>
				{icon}
				<span>{name}</span>
			</Link>
		);
	};

	conversionPath = (path) => {
		if (path && path.indexOf("http") === 0) {
			return path;
		}
		return `/${path || ""}`.replace(/\/+/g, "/");
	};

	render() {
		const { openKeys, theme, mode, location: { pathname }, className, collapsed, onCollapse } = this.props;
		// if pathname can't match, use the nearest parent's key
		let selectedKeys = this.getSelectedMenuKeys(pathname);
		if (!selectedKeys.length && openKeys) {
			selectedKeys = [openKeys[openKeys.length - 1]];
		};
		let props = {};
		if (openKeys && !collapsed) {
			props = {
				openKeys: openKeys.length === 0 ? [...selectedKeys] : openKeys,
			};
		};
		const { handleOpenChange, style, menuData } = this.props;
		const cls = classNames(className, {
			"top-nav-menu": mode === "horizontal",
		});

		return (
			<Menu
				key='Menu'
				mode={mode}
				theme={theme}
				onOpenChange={handleOpenChange}
				selectedKeys={selectedKeys}
				style={style}
				className={cls}
				{...props}
				onClick={() => onCollapse(false)}
			>
				{this.getNavMenuItems(menuData, selectedKeys[0])}
			</Menu>
		);
	}
}
